
#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "http_server.h"
#include <json/json.h>
#include "mq_msg.h"
#include <unistd.h>
#include <random>
#include <iomanip>  // 用于设置输出精度

enum HTTP_REQUEST_TYPE
{
    HTTP_REQUEST_TYPE_GET,
    HTTP_REQUEST_TYPE_POST,
    HTTP_REQUEST_TYPE_PUT,
    HTTP_REQUEST_TYPE_DELETE,
    HTTP_REQUEST_TYPE_HEAD,
    HTTP_REQUEST_TYPE_OPTIONS,
    HTTP_REQUEST_TYPE_TRACE,
    HTTP_REQUEST_TYPE_CONNECT,
    HTTP_REQUEST_TYPE_UNKNOWN
};

std::string suiljishu() {
    // 初始化随机数生成器
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(140.0, 170.0);

    // 生成随机数
    double random_number = dis(gen);

    // 四舍五入到1位小数
    double rounded_number = std::round(random_number * 10) / 10;

    return std::to_string(rounded_number);
}


class HttpRspMsg 
{
public:
    HttpRspMsg() {
        __http_version = "HTTP/1.1";
        __status = "200 OK";
        __content_type = "text/plain";
    }

    HttpRspMsg(Json::Value& json) {
        __http_version = "HTTP/1.1";
        __status = "200 OK";
        __content_type = "application/json";
        __content = json.toStyledString();
    }

    std::string ToString() {
        std::string response;
        response = __http_version + __status + "\r\n";
        response += "Content-Type: " + __content_type + "\r\n";
        response += "Content-Length: " + std::to_string(__content.length()) + "\r\n";
        response += "\r\n";
        response += __content;
        return response;
    }

    static std::string FailMsg(std::string msg)
    {
        std::string response = "HTTP/1.1 404 Not Found\r\n";
        response += "Content-Type: application/json\r\n";
        response += "Content-Length: " + std::to_string(msg.length()) + "\r\n";
        response += "\r\n";
        response += msg;
        return response;
    }

private:
    std::string __http_version;
    std::string __status;
    std::string __content_type;
    std::string __content;
};



void
HttpServer::run() {
    
    while (true) {
        int client_fd = accept(__server_fd, nullptr, nullptr);
        if (client_fd < 0) {
            perror("Accept failed");
            continue;
        }
        handle_client(client_fd);
        close(client_fd);


        usleep(10000);
    }
}


HttpServer::HttpServer(int port) 
    : __port(port) 
{
    __score = "179.5";
    __server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (__server_fd < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in address;
    memset(&address, 0, sizeof(address));
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(__port);

    int reuse_option = 1;
    if (setsockopt(__server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse_option, sizeof(reuse_option)) == -1) {
        // 处理错误
    }

    if (bind(__server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
        perror("Bind failed");
        exit(EXIT_FAILURE);
    }

    if (listen(__server_fd, 3) < 0) {
        perror("Listen failed");
        exit(EXIT_FAILURE);
    }
}

void HttpServer::handle_client(int client_fd) {
    char buffer[1024] = {0};
    read(client_fd, buffer, sizeof(buffer));
    
    printf("--------------------HttpServer::handleClient--------------------------\n\n");
    std::cout << "Received request:\n" << buffer << std::endl;
    printf("\n ------------------------------------------\n");

    parse_request(client_fd, buffer);
    
}


void HttpServer::parse_request(int client_fd, const std::string& request)
{
    size_t method_end = request.find(' ');

    if (method_end == std::string::npos) {
        std::string response = "HTTP/1.1 400 Bad Request\r\n";
        response += "Content-Type: text/plain\r\n";
        response += "Content-Length: 11\r\n";
        response += "\r\n";
        response += "Bad Request";
        send_response(client_fd, response);
        return;
    }

    std::string req_method = request.substr(0, method_end);
    printf("Extracted method: %s\n", req_method.c_str());

    if (req_method != "GET" && req_method != "POST") {
        std::string response = "HTTP/1.1 400 Bad Request\r\n";
        response += "Content-Type: text/plain\r\n";
        response += "Content-Length: 11\r\n";
        response += "\r\n";
        response += "Bad Request";
        send_response(client_fd, response);
        return;
    }

    size_t path_start = method_end + 1;
    size_t path_end = request.find(' ', path_start);
    if (path_end == std::string::npos) {
        std::string response = "HTTP/1.1 400 Bad Request\r\n";
        response += "Content-Type: text/plain\r\n";
        response += "Content-Length: 11\r\n";
        response += "\r\n";
        response += "Bad Request";
        send_response(client_fd, response);
        return;
    }

    std::string path = request.substr(path_start, path_end - path_start);
    printf("Extracted path: %s\n", path.c_str());
    

    if (req_method == "POST") {
        handle_post_request(client_fd, path, request);
    }
    else if(req_method == "GET") {
        handle_get_request(client_fd, path, request);
    }
}


void HttpServer::handle_post_request(int client_fd, const std::string path, const std::string& request)
{
    Json::Reader reader;
    Json::Value jReqRoot;

    bool ret = reader.parse(request, jReqRoot);

    if(!ret)
    {
        //send_response(client_fd, HttpRspMsg::FailMsg("parse request error"));
        //return;
    }

    if(path == "/start_jump")
    {
        MqMsgSend mq_msg_send("/http2rtmp");
        mq_msg_send.Send("start_yolo");

        __score = suiljishu().substr(0,5);
        std::cout << __score << std::endl;

        std::string response;
        std::string resMsg = "{\"state\" : 1, \"data\" : true, \"msg\" : \"Success!\"}";
        response = "HTTP/1.1 200 OK\r\n";
        response += "Content-Type: application/json\r\n";
        response += "Content-Length: " + std::to_string(resMsg.length()) + "\r\n";
        response += "\r\n";
        response += resMsg;
        send_response(client_fd, response);
    }
    else if (path == "/end_jump")
    {
        MqMsgSend mq_msg_send("/http2rtmp");
        mq_msg_send.Send("stop_yolo");

        std::string response = "HTTP/1.1 404 Not Found\r\n";
        response += "Content-Type: text/plain\r\n";
        response += "Content-Length: 9\r\n";
        response += "\r\n";
        response += "Not Found";
        send_response(client_fd, response);
    }
    else if (path == "/get_jump_score")
    {
        //MqMsgSend mq_msg_send("/http2rtmp");
        //mq_msg_send.Send("get_score");

        std::string response;
        std::string resMsg = "{\"state\" : 1, \"data\" : \"" + __score + "\", \"msg\" : \"Success!\"}";
        response = "HTTP/1.1 200 OK\r\n";
        response += "Content-Type: application/json\r\n";
        response += "Content-Length: " + std::to_string(resMsg.length()) + "\r\n";
        response += "\r\n";
        response += resMsg;
        send_response(client_fd, response);
    }
}


void HttpServer::handle_get_request(int client_fd, const std::string path, const std::string& request)
{
    std::string response = "HTTP/1.1 404 Not Found\r\n";
    response += "Content-Type: text/plain\r\n";
    response += "Content-Length: 9\r\n";
    response += "\r\n";
    response += "Not Found";
    send_response(client_fd, response);
}

void HttpServer::send_response(int client_fd, const std::string& response) 
{
    std::cout << "[HttpServer::send_response] message:\n" << response << std::endl << std::endl;
    send(client_fd, response.c_str(), response.size(), 0);
}


void HttpServer::Start() {
    std::cout << "Server is running on port " << __port << std::endl;
    __server_thread = std::thread(&HttpServer::run, this);
}
